##############
``config.yml``
##############

.. list-table::
   :widths: auto

   * - YAML File
     - ``config.yml``
   * - Schema File
     - ``configschema.json``
   * - Loader Class
     - :class:`yaml.SafeLoader`
   * - Dumper Class
     - :class:`ng911ok.lib.config_dataclasses.ConfigDumper`
   * - Python Module
     - :mod:`ng911ok.lib.session`
   * - Python Variable
     - :data:`~ng911ok.lib.session.config`

The schema of an Oklahoma-Standards-Compliant NG911 geodatabase is described by the ``config.yml`` file.

YAML Structure
==============

Top-Level Keys
--------------

The root object is a mapping with the ``!NG911Config`` tag applied.

.. list-table::
   :widths: auto


   * - ``gdb_info``
     - Mapping describing miscellaneous properties of the geodatabase as a whole.
   * - ``domains``
     - Sequence of mappings, each defining the properties of one geodatabase domain.
   * - ``fields``
     - Sequence of mappings, each defining a field used by NG911 feature classes.
   * - ``feature_classes``
     - Sequence of mappings, each defining the properties of one NG911 feature class.

Tags
----

Constructors are registered in :mod:`ng911ok.lib.session` and :mod:`ng911ok.lib.config_dataclasses`.

.. list-table::
   :widths: auto

   * - ``!NG911Config``
     - Applied to the root mapping of ``config.yml``.
   * - ``!GDBInfo``
     - Applied to the top-level ``gdb_info`` key.
   * - ``!CompleteDomainList``
     - Applied to the top-level ``domains`` key.
   * - ``!Domain``
     - Indicates a domain definition under the ``domains`` key.
   * - ``!CompleteFieldList``
     - Applied to the top-level ``fields`` key.
   * - ``!Field``
     - Indicates a field definition under the ``fields`` key.
   * - ``!FeatureClassList``
     - Applied to the top-level ``feature_classes`` key.
   * - ``!FeatureClass/*``
     - Series of tags each indicating a feature class definition, where ``*`` is a placeholder for a PascalCase name of a feature class.

Anchors
-------

.. list-table::
   :widths: auto

   * - ``&required_dataset_name``
     - Name of the required feature dataset. Intended for use in the ``dataset`` keys of mappings under the top-level ``feature_classes`` key.
   * - ``&optional_dataset_name``
     - Name of the optional feature dataset. Intended for use in the ``dataset`` keys of mappings under the top-level ``feature_classes`` key.

Domain Anchors
^^^^^^^^^^^^^^

Every domain under the ``domains`` top-level key should have an anchor whose name is equal to the ``name`` key of the domain with which it is associated. Every use of the ``!Domain`` tag in ``config.yml`` should also have such an anchor. These anchors are intended for use in the ``domain`` keys of mappings under the top-level ``fields`` key.

Field Anchors
^^^^^^^^^^^^^

Every field under the ``fields`` top-level key should have an anchor whose name is equal to the ``role`` key of the field with which it is associated. Every use of the ``!Field`` tag in ``config.yml`` should also have such an anchor. These anchors are intended for use in the ``fields`` keys of mappings under the top-level ``feature_classes`` key.

Python Implementation
=====================

The ``config`` Variable
-----------------------

The module :mod:`ng911ok.lib.session` provides the :class:`~ng911ok.lib.session._NG911Config` class, which implements the ``!NG911Config`` tag, and its only instance, :data:`~ng911ok.lib.session.config`, which exposes the data stored in ``config.yml``.

Constructors for ``!CompleteDomainList``, ``!CompleteFieldList``, ``!FeatureClassList``, and ``!FeatureClass/*`` are registered in :mod:`ng911ok.lib.session`. The remaining tags are implemented as subclasses of ``yaml.YAMLObject`` in :mod:`ng911ok.lib.config_dataclasses`.

Namespace Classes and ``fctypes.py``
------------------------------------

The ``!FeatureClass/*`` constructor returns an instance of :class:`ng911ok.lib.config_dataclasses.NG911FeatureClass`. The type of the returned instance's :attr:`~ng911ok.lib.config_dataclasses.NG911FeatureClass.fields` attribute depends on the tag's suffix (the part after the slash, such as ``AddressPoint`` in ``!FeatureClass/AddressPoint``). More specifically, that attribute will be an instance of the class ``NG911<tag_suffix>FieldNamespace``, where ``<tag_suffix>`` is the suffix previously described. All such classes are defined in :mod:`ng911ok.lib.fctypes`.

The ``fctypes`` module is unique in the ``ng911ok`` package in that it is programmatically generated. It should not be manually edited. If some sort of change is necessary, it should be accounted for in ``generate_fctypes.py``, which is responsible for generating the code in ``fctypes``. Having classes that correspond to the YAML helps provide for type-checking and autocomplete in IDEs.